package basic;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import util.json.JSONUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 值引用测试
 */
@Slf4j
public class ValueReferenceTest {
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    static class Student {
        private Long id;
        private String name;
        private Integer age;
    }

    public static void main(String[] args) {
        Student student = new Student();
        student.setId(1L);
        student.setName("张三");
        student.setAge(10);

        Student student2 = student;
        student2.setName("李四");

        log.info("student：{}", JSONUtils.json(student));    //{"id":1,"name":"李四","age":10}
        log.info("student2：{}", JSONUtils.json(student2));  //{"id":1,"name":"李四","age":10}

        Student student3 = new Student();
        student3 = student2;
        student3.setName("王五");

        log.info("student：{}", JSONUtils.json(student));    //{"id":1,"name":"王五","age":10}
        log.info("student2：{}", JSONUtils.json(student2));  //{"id":1,"name":"王五","age":10}
        log.info("student3：{}", JSONUtils.json(student3));  //{"id":1,"name":"王五","age":10}

        student = new Student();
        student.setId(1L);
        student.setName("张三");
        student.setAge(10);
        List<Student> list2 = new ArrayList<>();
        list2.add(student);
        log.info("list2：{}", JSONUtils.json(list2));    //[{"id":1,"name":"张三","age":10}]

        List<Student> list3 = new ArrayList<>();
        list3.add(list2.get(0));
        log.info("list3：{}", JSONUtils.json(list3));    //[{"id":1,"name":"张三","age":10}]

        Student student1 = list3.get(0);
        student1.setName("李四");

        log.info("list2：{}", JSONUtils.json(list2));    //[{"id":1,"name":"李四","age":10}]
        log.info("list3：{}", JSONUtils.json(list3));    //[{"id":1,"name":"李四","age":10}]

        student = new Student();
        student.setId(1L);
        student.setName("张三");
        student.setAge(10);
        List<Student> list4 = new ArrayList<>();
        list4.add(student);

        changeList(list4);
        log.info("list4：{}", JSONUtils.json(list4));    //[{"id":1,"name":"张三","age":10}]
    }

    private static void changeList(List<Student> list) {
        Student student = new Student();
        student.setId(2L);
        student.setName("李四");
        student.setAge(20);
        List<Student> list2 = new ArrayList<>();
        list2.add(student);
        list = list2;
    }
}

@Slf4j
class ReferenceTest {
    public static void main(String[] args) {
        Integer a = 1;

        Integer b = a;
        b = 2;
        log.info("a：{}", a);    // 1
        log.info("b：{}", b);    // 2

        a = null;
        log.info("a：{}", a);    // null
        log.info("b：{}", b);    // 2
    }
}

@Slf4j
class ListValueReferenceTest {
    public static void main(String[] args) {
        ListValueReferenceTest test = new ListValueReferenceTest();

        List<Integer> list = new ArrayList<>();

        test.add(list);
        list.forEach(System.out::println);  //1

        test.add2(list);
        list.forEach(System.out::println);  //1

        test.add3(list);
        list.forEach(System.out::println);  //1 2 3


        List<ValueReferenceTest.Student> studentList = new ArrayList<>();

        test.add4(studentList);
        studentList.forEach(System.out::println);  //ValueReferenceTest.Student(id=1, name=张三1, age=10)

        test.add5(studentList);
        studentList.forEach(System.out::println);  //ValueReferenceTest.Student(id=1, name=张三1, age=10)

        test.add6(studentList);
        studentList.forEach(System.out::println);
//        ValueReferenceTest.Student(id=1, name=张三1, age=10)
//        ValueReferenceTest.Student(id=4, name=张三4, age=10)
//        ValueReferenceTest.Student(id=5, name=张三5, age=10)
    }

    private void add(List<Integer> list) {
        list.add(1);
    }

    private void add2(List<Integer> list) {
        List<Integer> integerList = new ArrayList<>();
        integerList.add(2);
        integerList.add(3);

        list = integerList;
    }

    private void add3(List<Integer> list) {
        List<Integer> integerList = new ArrayList<>();
        integerList.add(2);
        integerList.add(3);

        list.addAll(integerList);
//        list.addAll(null);  //NullPointerException
    }

    private void add4(List<ValueReferenceTest.Student> list) {
        list.add(new ValueReferenceTest.Student(1L, "张三1", 10));
    }

    private void add5(List<ValueReferenceTest.Student> list) {
        List<ValueReferenceTest.Student> integerList = new ArrayList<>();
        integerList.add(new ValueReferenceTest.Student(2L, "张三2", 10));
        integerList.add(new ValueReferenceTest.Student(3L, "张三3", 10));

        list = integerList;
    }

    private void add6(List<ValueReferenceTest.Student> list) {
        List<ValueReferenceTest.Student> integerList = new ArrayList<>();
        integerList.add(new ValueReferenceTest.Student(4L, "张三4", 10));
        integerList.add(new ValueReferenceTest.Student(5L, "张三5", 10));

        list.addAll(integerList);
//        list.addAll(null);  //NullPointerException
    }
}

@Slf4j
class MapValueReferenceTest {
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        MapValueReferenceTest test = new MapValueReferenceTest();
        test.add(map);

        map.forEach((key, value) -> System.out.println(key + "-" + value));

        for (Map.Entry<String, String> entry : map.entrySet()) {
            System.out.println(entry.getKey() + "-" + entry.getValue());
        }
    }

    private void add(Map<String, String> map) {
        Map<String, String> stringMap = new HashMap<>();
        stringMap.put("1", "11");
        stringMap.put("2", "22");
        stringMap.put("3", "33");

        map.putAll(stringMap);
    }
}

class IntegerEqualTest {
    public static void main(String[] args) {
        Integer a = 128;
        Integer b = 128;
        Integer c = 127;
        Integer d = 127;
        System.out.println(a == 128); //true
        System.out.println(a == b);   //false
        System.out.println(c == d);   //true
    }
}

class BasicVariable{
    public static void main(String[] args) {
        BasicVariable basicVariable = new BasicVariable();

        int a = 0;
        System.out.println(a);  //0
        basicVariable.basicChange(a);
        System.out.println(a);  //0

        boolean b = false;
        System.out.println(b);  //false
        basicVariable.basicChange(b);
        System.out.println(b);  //false

        Boolean bb = false;
        System.out.println(bb); //false
        basicVariable.objectChange(bb);
        System.out.println(bb); //false
    }

    void basicChange(int a) {
        a = 1;
    }

    void basicChange(boolean b) {
        b = true;
    }

    void objectChange(Boolean bb) {
        bb = true;
    }
}